widget-factory: Demonstrate custom context menu items
authorMatthias Clasen <mclasen@redhat.com>
Sun, 7 Jun 2015 05:12:18 +0000 (01:12 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 7 Jun 2015 05:12:18 +0000 (01:12 -0400)
Add bold/italics/underline styling to the context menu of
the 'Lorem ipsum...' text view in page 1. The point is not
to show good UI for this kind of styling, but to demonstrate
custom actions in the context menu / touch selection.

demos/widget-factory/widget-factory.c
demos/widget-factory/widget-factory.ui

index 979b7f78e599586c536386e1fe16b96a57dc9fb2..10815ea81fb6e46ccf1b9911dee986c02f0a7ab4 100644 (file)
@@ -1124,6 +1124,93 @@ page_combo_separator_func (GtkTreeModel *model,
   return res;
 }
 
+static void
+activate_item (GtkWidget *item, GtkTextView *tv)
+{
+  const gchar *tag;
+  GtkTextIter start, end;
+  gboolean active;
+
+  g_object_get (item, "active", &active, NULL);
+  tag = (const gchar *)g_object_get_data (G_OBJECT (item), "tag");
+  gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer (tv), &start, &end);
+  if (active)
+    gtk_text_buffer_apply_tag_by_name (gtk_text_view_get_buffer (tv), tag, &start, &end);
+  else
+    gtk_text_buffer_remove_tag_by_name (gtk_text_view_get_buffer (tv), tag, &start, &end);
+}
+
+static void
+add_item (GtkTextView *tv,
+          GtkWidget   *popup,
+          const gchar *label,
+          const gchar *tag,
+          gboolean     set)
+{
+  GtkWidget *item;
+
+  if (GTK_IS_MENU (popup))
+    {
+      item = gtk_check_menu_item_new_with_label (label);
+      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), set);
+      g_signal_connect (item, "toggled", G_CALLBACK (activate_item), tv);
+    }
+  else
+    {
+      item = gtk_check_button_new_with_label (label);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), set);
+      g_signal_connect (item, "clicked", G_CALLBACK (activate_item), tv);
+    }
+
+  g_object_set_data (G_OBJECT (item), "tag", (gpointer)tag);
+  gtk_widget_show (item);
+  gtk_container_add (GTK_CONTAINER (popup), item);
+}
+
+static void
+populate_popup (GtkTextView *tv,
+                GtkWidget   *popup)
+{
+  gboolean has_selection;
+  GtkWidget *item;
+  GtkTextIter start, end, iter;
+  GtkTextTagTable *tags;
+  GtkTextTag *bold, *italic, *underline;
+  gboolean all_bold, all_italic, all_underline;
+
+  has_selection = gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer (tv), &start, &end);
+
+  if (!has_selection)
+    return;
+
+  tags = gtk_text_buffer_get_tag_table (gtk_text_view_get_buffer (tv));
+  bold = gtk_text_tag_table_lookup (tags, "bold");
+  italic = gtk_text_tag_table_lookup (tags, "italic");
+  underline = gtk_text_tag_table_lookup (tags, "underline");
+  all_bold = TRUE;
+  all_italic = TRUE;
+  all_underline = TRUE;
+  gtk_text_iter_assign (&iter, &start);
+  while (!gtk_text_iter_equal (&iter, &end))
+    {
+      all_bold &= gtk_text_iter_has_tag (&iter, bold);
+      all_italic &= gtk_text_iter_has_tag (&iter, italic);
+      all_underline &= gtk_text_iter_has_tag (&iter, underline);
+      gtk_text_iter_forward_char (&iter);
+    }
+
+  if (GTK_IS_MENU (popup))
+    {
+      item = gtk_separator_menu_item_new ();
+      gtk_widget_show (item);
+      gtk_container_add (GTK_CONTAINER (popup), item);
+    }
+
+  add_item (tv, popup, "Bold", "bold", all_bold);
+  add_item (tv, popup, "Italics", "italic", all_italic);
+  add_item (tv, popup, "Underline", "underline", all_underline);
+}
+
 static void
 activate (GApplication *app)
 {
@@ -1327,6 +1414,10 @@ activate (GApplication *app)
   widget2 = (GtkWidget *)gtk_builder_get_object (builder, "totem_like_osd");
   g_object_set_data (G_OBJECT (widget), "osd", widget2);
 
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "textview1");
+  g_signal_connect (widget, "populate-popup",
+                    G_CALLBACK (populate_popup), NULL);
+
   gtk_widget_show_all (GTK_WIDGET (window));
 
   g_object_unref (builder);
index c7a7148446461ba0446d6657d3ab3468b988053c..8c0e3fd0ae415c1102d162ed80af63babb65fa41 100644 (file)
       </row>
     </data>
   </object>
+  <object class="GtkTextTagTable" id="tags">
+    <child type="tag">
+      <object class="GtkTextTag">
+        <property name="name">bold</property>
+        <property name="weight">800</property>
+      </object>
+    </child>
+    <child type="tag">
+      <object class="GtkTextTag">
+        <property name="name">italic</property>
+        <property name="style">italic</property>
+      </object>
+    </child>
+    <child type="tag">
+      <object class="GtkTextTag">
+        <property name="name">underline</property>
+        <property name="underline">single</property>
+      </object>
+    </child>
+  </object>
   <object class="GtkTextBuffer" id="textbuffer1">
+    <property name="tag-table">tags</property>
     <property name="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 Nullam fringilla, est ut feugiat ultrices, elit lacus ultricies nibh, id commodo tortor nisi id elit.
 Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
@@ -1408,6 +1429,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
                                 <property name="wrap_mode">2</property>
                                 <property name="left_margin">10</property>
                                 <property name="right_margin">10</property>
+                                <property name="populate_all">True</property>
                               </object>
                             </child>
                           </object>